namespace Meters
{
    using System;
    using System.ComponentModel;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Windows.Forms;

    [ToolboxBitmap(typeof(Timer))]
    public class Meter : UserControl
    {
        private bool _bHaveAction = false;
        private string _ScaleName = null;
        private Color bodyColor;
        private IContainer components = null;
        private double currValue;
        protected LBAnalogMeterRenderer defaultRenderer;
        protected float drawRatio;
        protected RectangleF drawRect;
        protected float endAngle;
        protected RectangleF glossyRect;
        private double maxValue;
        private double minValue;
        protected PointF needleCenter;
        private Color needleColor;
        protected RectangleF needleCoverRect;
        private LBAnalogMeterRenderer renderer;
        private Color scaleColor;
        private int scaleDivisions;
        private int scaleSubDivisions;
        protected float startAngle;
        private bool viewGlass;

        public Meter()
        {
            this.InitializeComponent();
            this.bodyColor = Color.Red;
            this.needleColor = Color.Yellow;
            this.scaleColor = Color.White;
            this.viewGlass = false;
            this.startAngle = 135f;
            this.endAngle = 405f;
            this.minValue = 0.0;
            this.maxValue = 100.0;
            this.currValue = 0.0;
            this.scaleDivisions = 11;
            this.scaleSubDivisions = 9;
            this.renderer = null;
            base.SetStyle(ControlStyles.DoubleBuffer, true);
            base.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            base.SetStyle(ControlStyles.UserPaint, true);
            this.defaultRenderer = new LBDefaultAnalogMeterRenderer();
            this.defaultRenderer.AnalogMeter = this;
            this.CalculateDimensions();
        }

        protected virtual void CalculateDimensions()
        {
            float num = 0f;
            float num2 = 0f;
            float width = base.Size.Width;
            float height = base.Size.Height;
            this.drawRatio = Math.Min(width, height) / 200f;
            if (this.drawRatio == 0.0)
            {
                this.drawRatio = 1f;
            }
            this.drawRect.X = num;
            this.drawRect.Y = num2;
            this.drawRect.Width = width - 2f;
            this.drawRect.Height = height - 2f;
            if (width < height)
            {
                this.drawRect.Height = width;
            }
            else if (width > height)
            {
                this.drawRect.Width = height;
            }
            if (this.drawRect.Width < 10f)
            {
                this.drawRect.Width = 10f;
            }
            if (this.drawRect.Height < 10f)
            {
                this.drawRect.Height = 10f;
            }
            this.needleCenter.X = this.drawRect.X + (this.drawRect.Width / 2f);
            this.needleCenter.Y = this.drawRect.Y + (this.drawRect.Height / 2f);
            this.needleCoverRect.X = this.needleCenter.X - (20f * this.drawRatio);
            this.needleCoverRect.Y = this.needleCenter.Y - (20f * this.drawRatio);
            this.needleCoverRect.Width = 40f * this.drawRatio;
            this.needleCoverRect.Height = 40f * this.drawRatio;
            this.glossyRect.X = this.drawRect.X + (20f * this.drawRatio);
            this.glossyRect.Y = this.drawRect.Y + (10f * this.drawRatio);
            this.glossyRect.Width = this.drawRect.Width - (40f * this.drawRatio);
            this.glossyRect.Height = this.needleCenter.Y + (30f * this.drawRatio);
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing && (this.components != null))
            {
                this.components.Dispose();
            }
            base.Dispose(disposing);
        }

        public float GetDrawRatio()
        {
            return this.drawRatio;
        }

        public float GetEndAngle()
        {
            return this.endAngle;
        }

        public PointF GetNeedleCenter()
        {
            return this.needleCenter;
        }

        public float GetStartAngle()
        {
            return this.startAngle;
        }

        private void InitializeComponent()
        {
            this.SuspendLayout();
            // 
            // Meter
            // 
            this.Name = "Meter";
            this.Size = new System.Drawing.Size(149, 150);
            this.ResumeLayout(false);

        }

        protected override void OnPaint(PaintEventArgs e)
        {
            RectangleF rc = new RectangleF(0f, 0f, (float) base.Width, (float) base.Height);
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
            if (this.renderer == null)
            {
                this.defaultRenderer.DrawBackground(e.Graphics, rc);
                this.defaultRenderer.DrawBody(e.Graphics, this.drawRect);
                this.defaultRenderer.DrawThresholds(e.Graphics, this.drawRect);
                this.defaultRenderer.DrawDivisions(e.Graphics, this.drawRect);
                this.defaultRenderer.DrawUM(e.Graphics, this.drawRect);
                this.defaultRenderer.DrawValue(e.Graphics, this.drawRect);
                this.defaultRenderer.DrawNeedle(e.Graphics, this.drawRect);
                this.defaultRenderer.DrawNeedleCover(e.Graphics, this.needleCoverRect);
                this.defaultRenderer.DrawGlass(e.Graphics, this.glossyRect);
            }
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
        }

        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
            this.CalculateDimensions();
            base.Invalidate();
        }

        public bool bHaveAction
        {
            get
            {
                return this._bHaveAction;
            }
            set
            {
                this._bHaveAction = value;
            }
        }

        [Description("Color of the body of the control"), Category("Appearance")]
        public Color BodyColor
        {
            get
            {
                return this.bodyColor;
            }
            set
            {
                this.bodyColor = value;
                base.Invalidate();
            }
        }

        [Description("Maximum value of the data"), Category("Behavior")]
        public double MaxValue
        {
            get
            {
                return this.maxValue;
            }
            set
            {
                this.maxValue = value;
                base.Invalidate();
            }
        }

        [Description("Minimum value of the data"), Category("Behavior")]
        public double MinValue
        {
            get
            {
                return this.minValue;
            }
            set
            {
                this.minValue = value;
                base.Invalidate();
            }
        }

        [Category("Appearance"), Description("Color of the needle")]
        public Color NeedleColor
        {
            get
            {
                return this.needleColor;
            }
            set
            {
                this.needleColor = value;
                base.Invalidate();
            }
        }

        [Browsable(false)]
        public LBAnalogMeterRenderer Renderer
        {
            get
            {
                return this.renderer;
            }
            set
            {
                this.renderer = value;
                if (this.renderer != null)
                {
                    this.renderer.AnalogMeter = this;
                }
                base.Invalidate();
            }
        }

        [Description("Color of the scale of the control"), Category("Appearance")]
        public Color ScaleColor
        {
            get
            {
                return this.scaleColor;
            }
            set
            {
                this.scaleColor = value;
                base.Invalidate();
            }
        }

        [Category("Appearance"), Description("Number of the scale divisions")]
        public int ScaleDivisions
        {
            get
            {
                return this.scaleDivisions;
            }
            set
            {
                this.scaleDivisions = value;
                this.CalculateDimensions();
                base.Invalidate();
            }
        }

        public string ScaleName
        {
            get
            {
                return this._ScaleName;
            }
            set
            {
                this._ScaleName = value;
            }
        }

        [Category("Appearance"), Description("Number of the scale subdivisions")]
        public int ScaleSubDivisions
        {
            get
            {
                return this.scaleSubDivisions;
            }
            set
            {
                this.scaleSubDivisions = value;
                this.CalculateDimensions();
                base.Invalidate();
            }
        }

        [Description("Value of the data"), Category("Behavior")]
        public double Value
        {
            get
            {
                return this.currValue;
            }
            set
            {
                double maxValue = value;
                if (maxValue > this.maxValue)
                {
                    maxValue = this.maxValue;
                }
                if (maxValue < this.minValue)
                {
                    maxValue = this.minValue;
                }
                this.currValue = maxValue;
                base.Invalidate();
            }
        }

        [Category("Appearance"), Description("Show or hide the glass effect")]
        public bool ViewGlass
        {
            get
            {
                return this.viewGlass;
            }
            set
            {
                this.viewGlass = value;
                base.Invalidate();
            }
        }
    }
}

